package com.zmn.oms.zmn.normal.business.impl.discount;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.base.common.data.common.dro.marketing.shop.MarketingShopDRO;
import com.zmn.base.common.data.common.query.marketing.shop.MarketingShopVerifyQuery;
import com.zmn.base.common.data.dubbo.interfaces.marketing.shop.MarketingShopListRemoteService;
import com.zmn.base.price.common.dto.ProductPriceDRO;
import com.zmn.base.price.common.dto.ProductPriceQuery;
import com.zmn.base.price.dubbo.interfaces.calculate.ProductPriceRemoteService;
import com.zmn.base.price.dubbo.interfaces.calculate.ProductTariffRemoteService;
import com.zmn.biz.engineer.dubbo.interfaces.discount.EngineerDiscountModifyRemoteService;
import com.zmn.ccb.common.model.number.NumberDRO;
import com.zmn.ccb.dubbo.interfaces.number.NumberListRemoteService;
import com.zmn.ccc.common.enums.CallTypeEnum;
import com.zmn.ccc.common.model.record.CdrRecordDRO;
import com.zmn.ccc.dubbo.interfaces.record.RecordRemoteService;
import com.zmn.coa.common.consts.CommonConsts;
import com.zmn.common.constant.FicoConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.math.MathUtil;
import com.zmn.common.utils.math.MoneyUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.consts.GlobalConsts;
import com.zmn.dms.common.enums.DiscountTypeEnums;
import com.zmn.dms.dubbo.interfaces.coup.coupon.CoupOnceCardRemoteService;
import com.zmn.manager.redis.RedisManager;
import com.zmn.market.dubbo.interfaces.shop.AppShopListRemoteService;
import com.zmn.oms.business.interfaces.messageV1.common.MessageSendBaseService;
import com.zmn.oms.business.interfaces.orderamount.OrderAmountCalcBService;
import com.zmn.oms.business.interfaces.orderamount.OrderDiscountCalcBService;
import com.zmn.oms.business.interfaces.work.OrderWorkAmountBService;
import com.zmn.oms.common.annotation.OrderWorkCasOperate;
import com.zmn.oms.common.annotation.ZsNormalOrderWorkLog;
import com.zmn.oms.common.constant.*;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.model.bo.orderamount.*;
import com.zmn.oms.model.bo.work.discount.UseTimesCoupBO;
import com.zmn.oms.model.bo.work.discount.WorkTimesCardInfoBO;
import com.zmn.oms.model.dto.acceptance.OrderWorkAcceptanceDTO;
import com.zmn.oms.model.dto.work.modify.amount.DiscountCouponDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsDiscountCouponDTO;
import com.zmn.oms.model.dto.work.modify.amount.ZsDiscountDTO;
import com.zmn.oms.model.entity.discount.OrderDiscount;
import com.zmn.oms.model.entity.order.OrderExtend;
import com.zmn.oms.model.entity.product.OrderProduct;
import com.zmn.oms.model.entity.shop.OrderExternalShop;
import com.zmn.oms.model.entity.work.OrderWork;
import com.zmn.oms.model.vo.work.OperatePermissionVO;
import com.zmn.oms.model.vo.work.modify.amount.ZsDiscountVO;
import com.zmn.oms.services.interfaces.order.OrderExtendService;
import com.zmn.oms.services.interfaces.product.OrderProductService;
import com.zmn.oms.services.interfaces.shop.OrderExternalShopService;
import com.zmn.oms.services.interfaces.work.OrderWorkService;
import com.zmn.oms.zmn.business.impl.discount.ZsOrderDiscountBServiceImpl;
import com.zmn.oms.zmn.business.interfaces.acceptance.OrderWorkAcceptanceBService;
import com.zmn.oms.zmn.business.interfaces.work.ZsOrderWorkOperatePermissionBService;
import com.zmn.oms.zmn.normal.business.interfaces.discount.ZsNormalOrderDiscountBService;
import com.zmn.pay.common.constant.PayConsts;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 类描述：啄木鸟-普通工单-优惠实现类
 *
 * @author heciqi
 * @date 2018/12/10 21:11
 */
@Slf4j
@Service
public class ZsNormalOrderDiscountBServiceImpl extends ZsOrderDiscountBServiceImpl implements ZsNormalOrderDiscountBService {

    private static final String TAG = "查询400呼叫号码";

    //@Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    //private SaleApplyCountModifyService saleApplyCountModifyService;

    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private EngineerDiscountModifyRemoteService engineerDiscountModifyRemoteService;


    @Reference(version = com.zmn.market.dubbo.DubboConsts.INTERFACE_VERSION, check = false)
    private AppShopListRemoteService appShopListRemoteService;
    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private ProductTariffRemoteService productTariffRemoteService;
    @Reference(version = com.zmn.base.engineer.common.constants.DubboConsts.INTERFACE_VERSION, check = false)
    private ProductPriceRemoteService productPriceRemoteService;
    @Reference(version = com.zmn.dms.dubbo.constant.DmsDubboConsts.INTERFACE_VERSION, check = false)
    private CoupOnceCardRemoteService coupOnceCardRemoteService;

    @DubboReference(version = com.zmn.ccc.dubbo.interfaces.DubboConsts.INTERFACE_VERSION, check = false)
    private RecordRemoteService recordRemoteService;

    @DubboReference(version = com.zmn.ccc.dubbo.interfaces.DubboConsts.INTERFACE_VERSION, check = false)
    private NumberListRemoteService numberListRemoteService;

    @DubboReference(version = com.zmn.market.dubbo.DubboConsts.INTERFACE_VERSION, check = false)
    private MarketingShopListRemoteService marketingShopListRemoteService;

    @Autowired
    private OrderWorkService orderWorkService;
    @Autowired
    protected OrderProductService orderProductService;
    @Autowired
    protected ZsOrderWorkOperatePermissionBService orderWorkOperatePermissionBService;
    @Autowired
    private OrderDiscountCalcBService orderDiscountCalcBService;
    @Autowired
    private OrderAmountCalcBService orderAmountCalcBService;
    @Autowired
    private OrderWorkAmountBService orderWorkAmountBService;
    @Autowired
    private MessageSendBaseService messageSendBaseService;
    @Autowired
    private OrderWorkAcceptanceBService orderWorkAcceptanceBService;

    @Resource
    OrderExtendService orderExtendService;

    @Resource
    private OrderExternalShopService orderExternalShopService;

    @Autowired
    private RedisManager redisManager;

    /**
     * 美团三级渠道ID
     */
    private static final Integer MT_CHANNEL_ID = 1032;

    /**
     * 口碑三级渠道ID
     */
    private static final Integer KB_CHANNEL_ID = 1052;

    @Override
    public ZsDiscountVO findDiscountVO(Long orderId, Long workId, Integer operateId)
            throws Exception {
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        List<OrderDiscount> orderDiscounts = orderDiscountService.listByOrderId(orderId);
        // 特殊优惠
        if (Objects.equals(operateId, OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE)) {
            return this.getSpecialDiscount(dbOrderWork, orderDiscounts);
        }
        // 人工优惠
        else {
            ZsDiscountVO discountVO = this.getArtificialDiscount(dbOrderWork, orderDiscounts);

            // 外呼号码
            String calledNumber = this.getCalledNumber(orderId);

            // 外部店铺ID
            String externalShopId = this.getExternalShopId(orderId, workId);

            // 城市ID
            Integer cityId = dbOrderWork.getCityId();

            List<MarketingShopDRO> marketList;
            if(StringUtil.isNotBlank(externalShopId)){
                marketList = getMarketingShopListWithExternalShopId(externalShopId,cityId);
            }else if(StringUtil.isNotBlank(calledNumber)){
                marketList = getMarketingShopListWithCalledNumber(calledNumber,cityId);
            }else{
                marketList = new ArrayList<>();
            }

            if(CollectionUtil.isNullOrEmpty(marketList)){
                // 美团
                discountVO.setSupportMtCoupon(Boolean.FALSE);
                // 口碑
                discountVO.setSupportKbCoupon(Boolean.FALSE);

                return discountVO;
            }

            // 美团店铺
            List<MarketingShopDRO> mtMarketList = marketList.stream()
                    .filter(market -> Objects.equals(MT_CHANNEL_ID, market.getChannelThrId()))
                    .collect(Collectors.toList());

            // 口碑店铺
            List<MarketingShopDRO> kbMarketList = marketList.stream()
                    .filter(market -> Objects.equals(KB_CHANNEL_ID, market.getChannelThrId()))
                    .collect(Collectors.toList());

            if(CollectionUtil.isNotNullOrEmpty(mtMarketList)){
                discountVO.setSupportMtCoupon(Boolean.TRUE);
            }

            if(CollectionUtil.isNotNullOrEmpty(kbMarketList)){
                discountVO.setSupportKbCoupon(Boolean.TRUE);
            }

            return discountVO;
        }
    }


    /**
     * 人工优惠
     * @param dbOrderWork
     * @param orderDiscounts
     * @return
     */
    private ZsDiscountVO getArtificialDiscount(OrderWork dbOrderWork, List<OrderDiscount> orderDiscounts) throws OmsBaseException {
        List<OrderDiscount> artificialDiscountList = orderDiscounts.stream()
                .filter(e -> Objects.equals(e.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL))
                .collect(Collectors.toList());
        if (artificialDiscountList.size() > 1) {
            throw new OmsBaseException("人工优惠数量异常");
        }
        Integer discountAmount = null;
        if (CollectionUtil.isNotNullOrEmpty(artificialDiscountList)) {
            discountAmount = artificialDiscountList.get(0).getAmount();
        }

        // 获取最大人工优惠
        ReCalcOrderAmountDIO calcOrderAmountDIO = new ReCalcOrderAmountDIO();
        calcOrderAmountDIO.setOrderAmountDIO(BeanMapper.map(dbOrderWork, OrderAmountDIO.class));
        calcOrderAmountDIO.setDiscountConditionParamsDIO(BeanMapper.map(dbOrderWork, DiscountConditionParamsDIO.class));
        calcOrderAmountDIO.setOrderDiscountList(orderDiscounts);
        Integer artificialMaxDiscount = 0;
        try {
            artificialMaxDiscount = orderDiscountCalcBService.getArtificialMaxDiscount(TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_DISCOUNT, calcOrderAmountDIO);
        } catch (OmsBaseException e) {
            log.warn(e.getMessage(), e);
        }
        ZsDiscountVO discountVO = new ZsDiscountVO();
        discountVO.setOrderId(dbOrderWork.getOrderId());
        discountVO.setWorkId(dbOrderWork.getWorkId());
        discountVO.setDiscountAmount(discountAmount);
        discountVO.setMaxDiscountAmount(artificialMaxDiscount);
        return discountVO;
    }

    /**
     * 特殊优惠
     * @param dbOrderWork
     * @param orderDiscounts
     * @return
     */
    private ZsDiscountVO getSpecialDiscount(OrderWork dbOrderWork, List<OrderDiscount> orderDiscounts) throws OmsBaseException {
        List<OrderDiscount> artificialDiscountList = orderDiscounts.stream()
                .filter(e -> (Objects.equals(e.getSourceId(), DiscountConsts.BATCH_ID_FREE_DISCOUNT_HQ_COMPANY) || Objects.equals(e.getSourceId(), DiscountConsts.BATCH_ID_FREE_DISCOUNT_SUB_COMPANY)))
                .collect(Collectors.toList());
        if (artificialDiscountList.size() > 1) {
            throw new OmsBaseException("特殊优惠数量异常");
        }

        // 获取redis中缓存的折扣
        Integer discountAmount = null;
        Integer batchId = DiscountConsts.BATCH_ID_FREE_DISCOUNT_HQ_COMPANY;
        String redisKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_DISCOUNTAMOUNT_KEY, String.valueOf(dbOrderWork.getOrderId()));
        boolean isExists = redisManager.exists(redisKey);
        if (isExists) {
            discountAmount = Integer.valueOf(redisManager.get(redisKey));
            String batchIdKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_BATCHID_KEY, String.valueOf(dbOrderWork.getOrderId()));
            batchId = Integer.valueOf(redisManager.get(batchIdKey));
            //discountAmount = (int) MathUtil.div(discountAmount, 10);
        }

        // 获取最大优惠
        ReCalcOrderAmountDIO calcOrderAmountDIO = new ReCalcOrderAmountDIO();
        calcOrderAmountDIO.setOrderAmountDIO(BeanMapper.map(dbOrderWork, OrderAmountDIO.class));
        calcOrderAmountDIO.setDiscountConditionParamsDIO(BeanMapper.map(dbOrderWork, DiscountConditionParamsDIO.class));
        calcOrderAmountDIO.setOrderDiscountList(orderDiscounts);
        Integer artificialMaxDiscount = orderDiscountCalcBService.getArtificialMaxDiscount(TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_FREE_DISCOUNT, calcOrderAmountDIO);

        ZsDiscountVO discountVO = new ZsDiscountVO();
        discountVO.setOrderId(dbOrderWork.getOrderId());
        discountVO.setWorkId(dbOrderWork.getWorkId());
        discountVO.setDiscountAmount(discountAmount);
        discountVO.setDiscountBathId(batchId);
        discountVO.setMaxDiscountAmount(artificialMaxDiscount);
        if (CollectionUtil.isNotNullOrEmpty(artificialDiscountList)) {
            discountVO.setDiscountBathId(artificialDiscountList.get(0).getSourceId());
        }
        return discountVO;
    }


    /**
     * 获取最大可优惠金额
     */
    @Override
    @Deprecated
    public Integer getMaxDiscountAmount(Long orderId, Long workId, Integer operateId, Integer discountCateg) throws OmsBaseException {

        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        Integer originalAmount = dbOrderWork.getOriginalAmount();
        Integer prepayAmount = Optional.ofNullable(dbOrderWork.getPrepayAmount()).orElse(0);
        Integer channelPrepayAmount = Optional.ofNullable(dbOrderWork.getChannelPrepayAmount()).orElse(0);
        prepayAmount = prepayAmount + channelPrepayAmount;
        Integer depositAmount = Optional.ofNullable(dbOrderWork.getDepositAmount()).orElse(0);
        Integer discountAmount = Optional.ofNullable(dbOrderWork.getDiscountAmount()).orElse(0);
        Integer masterAmount = Optional.ofNullable(dbOrderWork.getMasterAmount()).orElse(0);

        if (originalAmount == null) {
            throw new OmsBaseException("原价为空 无法操作优惠");
        }

        if (discountAmount != 0) {
            // 剔除掉人工优惠金额
            List<OrderDiscount> discountList = orderDiscountService.listByOrderId(orderId);
            int sum = discountList.stream()
                    .filter(e -> Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_OPERATOR) || Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_MASTER))
                    .mapToInt(e -> e.getAmount())
                    .sum();
            discountAmount -= sum;
        }

        List<OrderProduct> orderProductList = orderProductService.listOrderProductByOrderId(dbOrderWork.getOrderId());
        int orderProductSum = orderProductList.stream().mapToInt(OrderProduct::getNumber).sum();

        // 最大优惠金额
        Integer maxDiscountAmount = 0;

        //   A：订单金额 / 产品数量 ≤ 50 元 或 优惠类型：全免优惠,Xiewenbing 2019.11.30
        //   则 MAX 优惠金额 = 订单金额 - 预付款 - 定金 - 其他优惠金额
        boolean supportFree = MathUtil.div(originalAmount, orderProductSum, 2) <= 5000;
        if ((supportFree || Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE, operateId))&&
                Objects.equals(discountCateg, FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_OPERATOR)) {
            maxDiscountAmount = originalAmount - prepayAmount - depositAmount - discountAmount;
        } else {
            // 优惠等级
            boolean isOneLevel = Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_ONE, operateId);
//            boolean isTwoLevel = Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_TWO, operateId);
//            boolean isThreeLevel = Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_LEVEL_THREE, operateId);
            if (isOneLevel) {
                // MAX1 = 订单金额 * 6折
                // MAX2 = 订单金额 - 预付款- 定金 - 其他优惠金额
                // MAX在于上两者取其小
                Double maxDiscountAmountOne = MathUtil.mul(originalAmount, OrderConsts.DISCOUNT_LEVEL_ONE_VALUE);
                Integer maxDiscountAmountTwo = originalAmount - prepayAmount - depositAmount - discountAmount;
                maxDiscountAmount = NumberUtil .toInteger(Math.min(maxDiscountAmountOne, maxDiscountAmountTwo));
            }
//            else if (isTwoLevel) {
//                // MAX1 = 订单金额 * 7折
//                // MAX2 = 订单金额 - 预付款- 定金 - 其他优惠金额
//                // MAX在于上两者取其小
//                Double maxDiscountAmountOne = MathUtil.mul(originalAmount, OrderConsts.DISCOUNT_LEVEL_TWO_VALUE);
//                Integer maxDiscountAmountTwo = originalAmount - prepayAmount - depositAmount - discountAmount;
//                maxDiscountAmount = NumberUtil.toInteger(Math.min(maxDiscountAmountOne, maxDiscountAmountTwo));
//            } else if (isThreeLevel) {
//                // MAX1 = 订单金额 * 9折
//                // MAX2 = 订单金额 - 预付款- 定金 - 其他优惠金额
//                // MAX在于上两者取其小
//                Double maxDiscountAmountOne = MathUtil.mul(originalAmount, OrderConsts.DISCOUNT_LEVEL_THREE_VALUE);
//                Integer maxDiscountAmountTwo = originalAmount - prepayAmount - depositAmount - discountAmount;
//                maxDiscountAmount = NumberUtil.toInteger(Math.min(maxDiscountAmountOne, maxDiscountAmountTwo));
//            }

            // B 若折扣 > 订单金额-预付款-定金，则最大优惠金额 = 订单金额-预付款-定金 - 其他优惠，反之，最大优惠金额 = 折扣
            if (maxDiscountAmount > (originalAmount - prepayAmount - depositAmount)) {
                maxDiscountAmount = originalAmount - prepayAmount - depositAmount - discountAmount;
            }
        }

        return maxDiscountAmount;
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USE_COUPON)
    @Transactional(rollbackFor = Exception.class)
    public void saveCouponOperator(ZsDiscountCouponDTO couponDTO) throws OmsBaseException {
    /*    OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(couponDTO.getOrderId(), couponDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_DISCOUNT_COUPON);
        if (!operatePermission.getCanOperate()) {
            throw new OmsBaseException(operatePermission.getMsg());
        }

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(couponDTO.getOrderId(), couponDTO.getWorkId());

        // 如果之前有优惠券优惠 则退换给用户
        List<OrderDiscount> discountList = orderDiscountService.listByOrderId(couponDTO.getOrderId());
        if (!CollectionUtils.isEmpty(discountList)) {
            Optional<OrderDiscount> first = discountList.stream().filter(e -> Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON)).findFirst();
            if (first.isPresent()) {
                // 则退换给用户
                orderDiscountBService.deleteDiscount(couponDTO.getOrderId(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON);

                CoupItemDIO coupItemDIO = new CoupItemDIO();
                coupItemDIO.setOrderId(orderWork.getOrderId());
                coupItemDIO.setUseUserId(orderWork.getUserId());
                // 2 为已发放
                coupItemDIO.setStatus(GlobalConsts.YES);
                log.info("#oms#savethirdcoupon 退还优惠券入参：{}", JSON.toJSONString(coupItemDIO));
                ResponseDTO responseDTO = coupRemoteService.updateCoupItemStatus(coupItemDIO);
                log.info("#oms#savethirdcoupon 退还优惠券出参：{}", JSON.toJSONString(responseDTO));
            }

            // 计算优惠总金额
            int sum = discountList.stream().filter(e -> !Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON)).mapToInt(OrderDiscount::getAmount).sum();
            couponDTO.setTotalDiscountAmount(sum + couponDTO.getAmount());
            log.info("#oms#saveCouponOperator#{} 优惠总金额为：{}", couponDTO.getOrderId(), couponDTO.getTotalDiscountAmount());
        }

        // 用于解决 清洗单子 清洗产品 108   买的券是 售价88 面值98
        // 如果是清洗单
        // 若原价 > （渠道预收+啄木鸟预收+定金+优惠总额）
        // 则置人工优惠 = 订单金额 - （渠道预收+啄木鸟预收+定金+非人工优惠）
        if (NumberUtil.isNotNullOrZero(couponDTO.getChannelPrepayAmount()) && Objects.equals(orderWork.getServCategId(), GlobalConsts.SERV_CATEG_CLEAN)) {

            Integer originalAmount = Optional.ofNullable(orderWork.getOriginalAmount()).orElse(0);
            Integer depositAmount = Optional.ofNullable(orderWork.getDepositAmount()).orElse(0);
            Integer prepayAmount = Optional.ofNullable(orderWork.getPrepayAmount()).orElse(0);
            Integer discountAmount = couponDTO.getAmount();
            Integer channelPrepayAmount = couponDTO.getChannelPrepayAmount();
            Integer addAmount = discountAmount + depositAmount + prepayAmount + channelPrepayAmount;
            log.info("#oms#saveCouponOperator#{} 清洗订单：{} originalAmount：{}，depositAmount：{}，prepayAmount：{}，discountAmount：{}，channelPrepayAmount：{}", couponDTO.getOrderId(), originalAmount, depositAmount, prepayAmount, discountAmount, channelPrepayAmount);
            // 若原价 > （渠道预收+啄木鸟预收+定金+优惠总额）
            if (originalAmount > addAmount) {
                // 则置人工优惠 = 订单金额 - （渠道预收+啄木鸟预收+定金+非人工优惠）
                Integer operateDiscountAmount = originalAmount - (addAmount);
                AddDiscountDTO addDiscountDTO = new AddDiscountDTO();
                addDiscountDTO.setOrderId(couponDTO.getOrderId());
                addDiscountDTO.setWorkId(couponDTO.getWorkId());
                addDiscountDTO.setAmount(operateDiscountAmount);
                orderDiscountBService.operatorDiscount(addDiscountDTO);

                // 如果需要重新计算人工优惠
                if (!CollectionUtils.isEmpty(discountList)) {
                    // 非人工优惠和优惠券的优惠总额
                    int sum = discountList.stream().filter(e ->
                            !Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_COUPON) &&
                            !Objects.equals(e.getCateg(), FicoConsts.ORDER_IN_DISCOUNT_CATEG_ARTIFICIAL_OPERATOR)
                    ).mapToInt(OrderDiscount::getAmount).sum();
                    couponDTO.setTotalDiscountAmount(sum + operateDiscountAmount + couponDTO.getAmount());
                } else {
                    couponDTO.setTotalDiscountAmount(operateDiscountAmount + couponDTO.getAmount());
                }
            }
        }

        orderDiscountBService.couponDiscount(couponDTO);*/
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USE_COUPON)
    @Transactional(rollbackFor = Exception.class)
    public void saveCoupon(DiscountCouponDTO couponDTO) throws OmsBaseException{
        OrderWork orderWork = orderWorkService.findOrderWorkByKey(couponDTO.getOrderId(), couponDTO.getWorkId());
        if (couponDTO.getOrderAmountCalcBO() != null) {
            orderWorkAmountBService.updateAmountAndDiscount(couponDTO.getOrderAmountCalcBO(),orderWork);

            // 改价格删除尾款验收，需要工程师重新发起尾款验收
            OrderWorkAcceptanceDTO dto = new OrderWorkAcceptanceDTO();
            dto.setOrderId(couponDTO.getOrderId());
            dto.setWorkId(couponDTO.getWorkId());
            dto.setOperator(couponDTO.getOperator());
            dto.setOperatorId(couponDTO.getOperatorId());
            dto.setOperatorType(couponDTO.getOperatorType());
            orderWorkAcceptanceBService.clearPaymentAcceptance(dto, orderWork);
        }
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USE_COUPON)
    public void saveFailCouponOperator(ZsDiscountCouponDTO couponDTO) {
        // 空实现，保存失败日志
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USE_COUPON)
    public void saveFailCoupon(DiscountCouponDTO couponDTO) {
        // 空实现，保存失败日志
    }

    @Override
    @OrderWorkCasOperate(type = OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISCOUNT_ARTIFICIAL_OPERATOR, beforeProceed = false)
    @Transactional(rollbackFor = Exception.class)
    public void saveArtificialOperator(ZsDiscountDTO discountDTO, boolean couponDiscount) throws OmsBaseException {
        OrderWork dbOrderWork = null;
        if (couponDiscount) {
            OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(discountDTO.getOrderId(), discountDTO.getWorkId(), OrderConsts.ORDER_OP_TYPE_DISCOUNT_COUPON);
            if (!operatePermission.getCanOperate()) {
                throw new OmsBaseException(operatePermission.getMsg());
            }
        } else {
            if (Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE, discountDTO.getOperateId())) {
                OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(discountDTO.getOrderId(), discountDTO.getWorkId(), discountDTO.getOperateId());
                if (!operatePermission.getCanOperate()) {
                    throw new OmsBaseException(operatePermission.getMsg());
                }
            } else {
                dbOrderWork = orderWorkService.findOrderWorkByKey(discountDTO.getOrderId(), discountDTO.getWorkId());
                OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.discountPermission(dbOrderWork);
                if (!operatePermission.getCanOperate()) {
                    throw new OmsBaseException(operatePermission.getMsg());
                }
            }
        }

        TriggerAmountChangeEnum triggerAmountChangeEnum;
        // 特殊优惠
        if (Objects.equals(OrderConsts.ORDER_OP_TYPE_DISCOUNT_FREE, discountDTO.getOperateId())) {
            if (NumberUtil.isNullOrZero(discountDTO.getDiscountBathId())) {
                throw new OmsBaseException("请选择优惠承担类型");
            }
            if (dbOrderWork == null) {
                dbOrderWork = orderWorkService.findOrderWorkByKey(discountDTO.getOrderId(), discountDTO.getWorkId());
            }
            ReCalcOrderAmountDIO reCalcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(dbOrderWork);
            if (!Objects.equals(GlobalConsts.YES, discountDTO.getRemoveDiscount())) {
                // 作废之前发放的特殊优惠券
                String oldRedisItemCodeKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_ITEMCODE_KEY, String.valueOf(dbOrderWork.getOrderId()));
                if (redisManager.exists(oldRedisItemCodeKey)) {
                    orderDiscountCalcBService.obsDiscountItemCodes(Lists.newArrayList(redisManager.get(oldRedisItemCodeKey)),discountDTO.getOrderId());
                    orderDiscountCalcBService.delRedisSpecialDiscountCoupon(dbOrderWork.getOrderId());
                }

                // 发放优惠券
                String itemCode = orderDiscountCalcBService.generateCouponDiscount(discountDTO.getOrderId(),
                        reCalcOrderAmountDIO.getDiscountConditionParamsDIO().getUserId(),
                        (int) MathUtil.div(discountDTO.getDiscountAmount(), 10),discountDTO.getDiscountBathId());
                // 重新记录新发放的优惠券
                String redisItemCodeKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_ITEMCODE_KEY, String.valueOf(dbOrderWork.getOrderId()));
                String redisDiscountAmountKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_DISCOUNTAMOUNT_KEY, String.valueOf(dbOrderWork.getOrderId()));
                String redisBatchIdKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_BATCHID_KEY, String.valueOf(dbOrderWork.getOrderId()));
                redisManager.set(redisItemCodeKey, itemCode);
                redisManager.set(redisDiscountAmountKey, String.valueOf(discountDTO.getDiscountAmount()));
                redisManager.set(redisBatchIdKey, String.valueOf(discountDTO.getDiscountBathId()));
                if (NumberUtil.isNullOrZero(dbOrderWork.getOriginalAmount())) {
                    return;
                }
            }
            triggerAmountChangeEnum = TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_FREE_DISCOUNT;
        }
        else {
            // 后台验券
            if (couponDiscount) {
                log.info("orderId:{} 开始后台验券：{}", discountDTO.getOrderId(), JSON.toJSONString(discountDTO));
                triggerAmountChangeEnum = TriggerAmountChangeEnum.VALIDATE_COUPON;
            }
            // 后台人工优惠
            else {
                triggerAmountChangeEnum = TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_DISCOUNT;
            }
        }

        // 外呼电话
        String calledNumber = this.getCalledNumber(discountDTO.getOrderId());
        if(StringUtil.isNotBlank(calledNumber)){
            discountDTO.setCalledNumber(calledNumber);
        }

        // 外部店铺ID
        String externalShopId = this.getExternalShopId(discountDTO.getOrderId(), discountDTO.getWorkId());
        if(StringUtil.isNotBlank(externalShopId)){
            discountDTO.setExternalShopId(externalShopId);
        }
        saveDiscount(discountDTO, triggerAmountChangeEnum);

        // 改价格删除尾款验收，需要工程师重新发起尾款验收
        try {
            OrderWorkAcceptanceDTO dto = new OrderWorkAcceptanceDTO();
            dto.setOrderId(discountDTO.getOrderId());
            dto.setWorkId(discountDTO.getWorkId());
            dto.setOperator(discountDTO.getOperator());
            dto.setOperatorId(discountDTO.getOperatorId());
            dto.setOperatorType(discountDTO.getOperatorType());
            OrderWork newOrderWork = Optional.ofNullable(dbOrderWork).orElse(orderWorkService.findOrderWorkByKey(discountDTO.getOrderId(), discountDTO.getWorkId()));
            orderWorkAcceptanceBService.clearPaymentAcceptance(dto, newOrderWork);
        } catch (Exception e) {
            log.error(e.getMessage(),e);
        }

    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISCOUNT_ARTIFICIAL_MASTER)
    @Transactional(rollbackFor = Exception.class)
    public void saveArtificialMaster(ZsDiscountDTO discountDTO) throws OmsBaseException {
        /*List<OrderDiscount> discountList = orderDiscountService.listByOrderId(discountDTO.getOrderId());
        if (!discountList.isEmpty()) {
            boolean haveArtificial = discountList.stream().anyMatch(e -> Objects.equals(e.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL));
            if (haveArtificial) {
                throw new OmsBaseException("已有优惠");
            }
        }*/
        saveDiscount(discountDTO, TriggerAmountChangeEnum.ARTIFICIAL_MASTER_DISCOUNT);

        // 人工优惠次数
        this.addMasterApplyDiscountTimes(discountDTO.getOrderId(), discountDTO.getMasterId(), discountDTO.getDiscountAmount());
    }

    @Override
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_DISCOUNT_ARTIFICIAL_SP)
    @Transactional(rollbackFor = Exception.class)
    public void saveArtificialSp(ZsDiscountDTO discountDTO) throws OmsBaseException {
        OperatePermissionVO operatePermission = orderWorkOperatePermissionBService.getOperatePermission(discountDTO.getOrderId(), discountDTO.getWorkId(), discountDTO.getOperateId());
        if (!operatePermission.getCanOperate()) {
            throw new OmsBaseException(operatePermission.getMsg());
        }
        saveDiscount(discountDTO, TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_DISCOUNT);
    }

    @Override
    public void saveDiscount(ZsDiscountDTO discountDTO, TriggerAmountChangeEnum triggerAmountChangeEnum) throws OmsBaseException {
        OrderWork dbOrderWork = orderWorkService.findOrderWorkByKey(discountDTO.getOrderId(), discountDTO.getWorkId());

        ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(dbOrderWork);
        if(StringUtil.isNotBlank(discountDTO.getCalledNumber())){
            calcOrderAmountDIO.setCalledNumber(discountDTO.getCalledNumber());
        }
        if(StringUtil.isNotBlank(discountDTO.getExternalShopId())){
            calcOrderAmountDIO.setExternalShopId(discountDTO.getExternalShopId());
        }

        // 删除优惠
        if (Objects.equals(GlobalConsts.YES, discountDTO.getRemoveDiscount())) {
            if (Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_FREE_DISCOUNT)) { // 特殊优惠券删除
                // 作废优惠券
                String redisItemCodeKey = String.format(RedisKeyConsts.DISCOUNT_SPECIAL_ITEMCODE_KEY, String.valueOf(dbOrderWork.getOrderId()));
                orderDiscountCalcBService.obsDiscountItemCodes(Lists.newArrayList(redisManager.get(redisItemCodeKey)),discountDTO.getOrderId());
                // redis中清除特殊优惠券
                orderDiscountCalcBService.delRedisSpecialDiscountCoupon(dbOrderWork.getOrderId());
            }
            // 计算和更新工单金额
            OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.ARTIFICIAL_DISCOUNT_DELETE, calcOrderAmountDIO, discountDTO.getForceVerify());
            orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO,dbOrderWork);
            return;
        }

        // 人工优惠
        if (Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.ARTIFICIAL_OPERATE_DISCOUNT) || Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.ARTIFICIAL_MASTER_DISCOUNT)) {
            calcOrderAmountDIO.setNewArtificialDiscountAmount(discountDTO.getDiscountAmount());
            Integer artificialMaxDiscount = orderDiscountCalcBService.getArtificialMaxDiscount(triggerAmountChangeEnum, calcOrderAmountDIO);
            log.info("orderDiscountCalcBService.getArtificialMaxDiscount 出参：{}",artificialMaxDiscount);
            // 优惠金额不能超过上限
            if (artificialMaxDiscount < discountDTO.getDiscountAmount()) {
                throw new OmsBaseException("优惠金额超过上限");
            }
        }

        // 后台验券
        else if (Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.VALIDATE_COUPON)) {
            calcOrderAmountDIO.setInvoker(3);// 后台验券
            calcOrderAmountDIO.setThirdType(discountDTO.getDisCategory());
            calcOrderAmountDIO.setCouponCode(discountDTO.getCouponCode());
        } else

            // 计价器3.0 师傅优惠
            if (Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.ARTIFICIAL_MASTER_DISCOUNT_PROM)) {
                calcOrderAmountDIO.setMasterDiscountId(discountDTO.getMasterDiscountId());
            }

        // 计算和更新工单金额
        OrderAmountCalcBO orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(triggerAmountChangeEnum, calcOrderAmountDIO, discountDTO.getForceVerify());
        // 更新结果赋值到DTO，用于日志展示
        if (Objects.equals(triggerAmountChangeEnum, TriggerAmountChangeEnum.VALIDATE_COUPON) && orderAmountCalcBO != null) {
            discountDTO.setCouponPrepayChannelAmount(orderAmountCalcBO.getChannelPrepayAmount());
            OrderDiscountCalcBO orderDiscountCalcBO = orderAmountCalcBO.getOrderDiscountCalcBO();
            if (orderDiscountCalcBO != null && CollectionUtil.isNotNullOrEmpty(orderDiscountCalcBO.getOrderDiscountList())) {
                orderDiscountCalcBO.getOrderDiscountList()
                        .stream()
                        .filter(e -> Objects.equals(e.getThirdCode(), GlobalConsts.YES))
                        .findFirst().ifPresent(
                                e -> discountDTO.setCouponAmount(e.getAmount())
                        );
            }
        }
        orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO,dbOrderWork);
    }


    @Override
    public boolean addMasterApplyDiscountTimes(Long orderId, Integer masterId, Integer discountAmount) {

        if (NumberUtil.isNullOrZero(discountAmount) || NumberUtil.isNullOrZero(masterId)) {
            return false;
        }

        String redisKey = String.format(RedisKeyConsts.MASTER_APPLY_DISCOUNT_KEY, String.valueOf(orderId), masterId);
        if (redisManager.exists(redisKey)) {
            return true;
        }

        // 优惠次数
        log.info("新增优惠applySucessCallBackByEngineer次数入参masterId={}，orderId={} ", masterId, orderId);
        // todo fubiao
        log.info("addMasterApplyDiscountTimes#useDiscount 入参 [{}] [{}]",masterId,orderId);
        ResponseDTO<Boolean> resp = engineerDiscountModifyRemoteService.useDiscount(masterId, String.valueOf(orderId));
        log.info("addMasterApplyDiscountTimes#useDiscount 出参 [{}]",JSON.toJSONString(resp));
        if (!resp.isSuccess()) {
            log.info("订单号OrderId=[{}]applySucessCallBackByEngineer新增次数失败 ", orderId);
            return false;
        }

        // 由于单子不知道什么时候能完成，固在redis保存设置失效时间，默认为1年，工单取消和完成后自动删除
        redisManager.setex(redisKey, DateUtil.getNowFormatted(), 3600 * 24 * 5);

        return true;
    }

    @Override
    public boolean deleteOrderMasterApplyDiscountAndQuotation(Long orderId, Integer masterId) {
        // 删除redis 订单工程师申请优惠次数解绑
        String applyDiscountRedisRey = String.format(RedisKeyConsts.MASTER_APPLY_DISCOUNT_KEY, String.valueOf(orderId), masterId);
        if (redisManager.exists(applyDiscountRedisRey)) {
            redisManager.del(applyDiscountRedisRey);
        }

        // 审核标示
        String redisKeyReviewing = String.format(RedisKeyConsts.MASTER_APPLY_DISCOUNT_REVIEWING_KEY, String.valueOf(orderId), masterId);
        if (redisManager.exists(redisKeyReviewing)) {
            redisManager.del(redisKeyReviewing);
        }

        // 确认报价标示
        String confirmQuotationRedisKey = String.format(RedisKeyConsts.USER_HAVE_CONFIRM_QUOTATION_KEY, String.valueOf(orderId));
        if (redisManager.exists(confirmQuotationRedisKey)) {
            redisManager.del(confirmQuotationRedisKey);
        }

        return true;
    }

    @Override
    public WorkTimesCardInfoBO getOrderTimesDiscountInfo(Long orderId, Long workId) throws OmsBaseException {
        WorkTimesCardInfoBO bo = new WorkTimesCardInfoBO();
        bo.setOrderId(orderId);
        bo.setWorkId(workId);

        OrderWork orderWork = orderWorkService.findOrderWorkByKey(orderId, workId);
        if (orderWork == null) {
            throw new OmsBaseException("订单不存在");
        }
        List<OrderDiscount> orderDiscountList = orderDiscountService.listByOrderId(orderId);
        Optional<OrderDiscount> discountOptional = orderDiscountList.stream().filter(discount -> {
            return Objects.equals(discount.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_ONCECARD.getSubType());
        }).findFirst();
        if (!discountOptional.isPresent()) {
            throw new OmsBaseException("订单不存在次卡优惠，无法获取相关信息");
        }

        // 产品名称
        OrderProduct orderProduct = orderProductService.listOrderProductByOrderId(orderId).get(0);
        bo.setProductName(orderProduct.getShowProductName());
        bo.setServiceItemNumber(1);

        // 获取默认服务项
        ArrayList<Integer> productIdList = Lists.newArrayList(orderProduct.getShowProductId());

        ProductPriceQuery productPriceDIO = new ProductPriceQuery();
        productPriceDIO.setBizType(orderWork.getBizType());
        productPriceDIO.setCityId(orderWork.getCityId());
        productPriceDIO.setChannelId(orderWork.getChannelId());
        productPriceDIO.setProductIdList(productIdList);
        productPriceDIO.setShowType(CommonConsts.PRODUCT_SHOW_TYPE_FRONT);
        productPriceDIO.setBrandId(orderProduct.getBrandId());
        log.info("调用接口：bkProductPriceRemoteService.listProductPriceByQuery 【入参】:{} 【用户ID】：{}", JSON.toJSONString(productPriceDIO), orderWork.getUserId());
        List<ProductPriceDRO> erpProductList = productPriceRemoteService.listProductPriceByQuery(productPriceDIO).getData();
        log.info("调用接口：bkProductPriceRemoteService.listProductPriceByQuery【出参】:{} 【用户ID】：{}", JSON.toJSONString(erpProductList), orderWork.getUserId());
        if (CollectionUtils.isNotEmpty(erpProductList) && Objects.nonNull(erpProductList.get(0))
                && Objects.nonNull(erpProductList.get(0).getItemDRO())) {
            bo.setServiceItemPrice(erpProductList.get(0).getItemDRO().getPrice());
            bo.setServiceItemName(erpProductList.get(0).getItemDRO().getItemName());
        }

        OrderDiscount discount = discountOptional.get();
        bo.setDiscountAmount(discount.getAmount());


        return bo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @ZsNormalOrderWorkLog(type = OrderLogConsts.ORDER_LOG_TYPE_USE_TIMES_CARD, beforeProceed = false)
    public void useTimesDiscount(UseTimesCoupBO bo) throws OmsBaseException {

        OrderWork orderWork = orderWorkService.findOrderWorkByKeySrcMaster(bo.getOrderId(), bo.getWorkId());
        if (Objects.isNull(orderWork)) {
            throw new OmsBaseException("订单不存在");
        }
        if (!Objects.equals(orderWork.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                || orderWork.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
            return;
        }
        if (Objects.equals(orderWork.getMasterPayStatus(), PayConsts.PAY_STATUS_DONE)) {
            return;
        }

        ReCalcOrderAmountDIO calcOrderAmountDIO = orderAmountCalcBService.getReCalcOrderAmountDIO(orderWork);

        OrderAmountCalcBO orderAmountCalcBO = null;

        if (StringUtils.isNotBlank(bo.getTimesCoupCode())) {
            // 使用优惠券
            calcOrderAmountDIO.setOnceCardcouponCode(bo.getTimesCoupCode());

            orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.TIMES_DISCOUNT_ADD, calcOrderAmountDIO, null);

            if (Objects.nonNull(orderAmountCalcBO.getOrderDiscountCalcBO())) {
                Optional<OrderDiscount> discountOptional = orderAmountCalcBO.getOrderDiscountCalcBO().getOrderDiscountList()
                        .stream()
                        .filter(e -> Objects.equals(e.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_ONCECARD.getSubType()))
                        .findFirst();
                if (discountOptional.isPresent()) {
                    OrderDiscount discount = discountOptional.get();

                    StringBuilder sb = new StringBuilder();
                    sb.append("卡券批次：").append(discount.getSourceId()).append("\n");
                    sb.append("卡券类型：").append(DiscountTypeEnums.DISCOUNT_COUP_ONCECARD.getParentName())
                            .append("-")
                            .append(OrderConsts.getDiscountTypeName(discount.getType())).append("\n");
                    sb.append("卡券名称：").append("次卡").append("\n");
                    sb.append("卡券券码：").append(discount.getItemCode()).append("\n");
                    sb.append("实际优惠：").append(MoneyUtil.parseToYuan(discount.getAmount())).append("\n");

                    bo.setLogContent(sb.toString());
                }
            }

        } else {
            List<OrderDiscount> discountList = orderDiscountService.listByOrderId(bo.getOrderId());
            Optional<OrderDiscount> coupOptional = discountList.stream().filter(e -> Objects.equals(e.getCateg(), DiscountTypeEnums.DISCOUNT_COUP_ONCECARD.getSubType())).findFirst();

            if (coupOptional.isPresent()) {

                // 如果本身有次卡优惠券 删除
                orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.TIMES_DISCOUNT_DELETE, calcOrderAmountDIO, null);

                bo.setLogContent("删除订单权益卡");
            } else {
                // 只有人工优惠不刷新取优惠
                List<OrderDiscount> orderDiscountList = calcOrderAmountDIO.getOrderDiscountList();
                if (Objects.nonNull(orderDiscountList)) {
                    boolean onlyArtificial = orderDiscountList.stream()
                            .anyMatch(e -> Objects.equals(e.getCateg(), DiscountConsts.DISCOUNT_CATEG_ARTIFICIAL));
                    if (onlyArtificial) {
                        log.info("[{}}工程师获取最新优惠---只有人工优惠不刷新", bo.getWorkId());
                        return;
                    }
                }
                // 刷新价格
                orderAmountCalcBO = orderAmountCalcBService.reCalcOrderAmountAndDiscountAmount(TriggerAmountChangeEnum.REFRESH_DISCOUNT, calcOrderAmountDIO, null);

                bo.setLogContent("刷新订单优惠");
            }


        }
        //主从并发问题，发现订单已完成
        if (NumberUtil.isNotNullOrZero(orderWork.getChannelPrepayAmount()) || NumberUtil.isNotNullOrZero(orderAmountCalcBO.getChannelPrepayAmount())) {
            OrderWork orderWorkByKeySrcMaster = orderWorkService.findOrderWorkByKeySrcMaster(orderWork.getOrderId(), orderWork.getWorkId());
            if (!Objects.equals(orderWorkByKeySrcMaster.getResultStatus(), OrderStatusConsts.WORK_RESULT_DOING)
                    || orderWorkByKeySrcMaster.getStatus() >= OrderStatusConsts.WORK_STATUS_COMPLETE) {
                log.info("[{}}工程师获取最新优惠---查主库订单已完成，不处理", bo.getWorkId());
                return;
            }
        }
        orderWorkAmountBService.updateAmountAndDiscount(orderAmountCalcBO, orderWork);
    }


    /**
     * 获取400 外呼号码
     * @param orderId
     * @return
     */
    private String getCalledNumber(Long orderId){
        OrderExtend orderExtend = orderExtendService.findOrderExtendByOrderId(orderId);
        if(Objects.isNull(orderExtend)){
            log.error("[{}]，根据订单Id查询扩展数据为空",TAG);

            return GlobalConsts.SPLITER_EMPTY;
        }
        String callId = orderExtend.getCallId();
        log.info("[{}]，根据订单Id查询扩展数据返回：{}",TAG,callId);

        if(StringUtil.isBlank(callId)){
            return GlobalConsts.SPLITER_EMPTY;
        }

        String prefix = "ti";
        String replaceCallId;
        if(!callId.contains(prefix)){
            return GlobalConsts.SPLITER_EMPTY;
        }else{
            replaceCallId = callId.replace(prefix, GlobalConsts.SPLITER_EMPTY);
        }

        List<Long> callIds = Collections.singletonList(Long.valueOf(replaceCallId));
        log.info("[{}]，查询通话记录入参：{}",TAG,JSON.toJSONString(callIds));
        ResponseDTO<List<CdrRecordDRO>> recordResponse = recordRemoteService.listCdrRecordsByRecordIds(callIds);
        if(!recordResponse.isSuccess()){
            log.error("[{}]，查询通话记录请求失败，失败原因：{}",TAG,recordResponse.getMessage());

            return GlobalConsts.SPLITER_EMPTY;
        }

        List<CdrRecordDRO> recordList = recordResponse.getData();
        log.info("[{}]，查询通话记录返回response：{}",TAG,JSON.toJSONString(recordList));

        List<CdrRecordDRO> callTypeInList = recordList.stream()
                .filter(item -> Objects.equals(CallTypeEnum.IN.getCode(), item.getCallTypeCode()))
                .collect(Collectors.toList());

        if(CollectionUtil.isNullOrEmpty(callTypeInList)){
            return GlobalConsts.SPLITER_EMPTY;
        }

        CdrRecordDRO cdrRecordDRO = callTypeInList.get(GlobalConsts.NONE);
        String callee = cdrRecordDRO.getCallee();

        log.info("[{}]，根据中继号码查询外呼号码入参：{}",TAG,callee);
        ResponseDTO<NumberDRO> trunkNumberResponse = numberListRemoteService.getNumberByTrunkNumber(callee);
        if(!trunkNumberResponse.isSuccess() || Objects.isNull(trunkNumberResponse.getData())){
            log.error("[{}]，根据中继号码查询外呼号码请求失败，失败原因：{}",TAG,trunkNumberResponse.getMessage());

            return com.zmn.consts.GlobalConsts.SPLITER_EMPTY;
        }

        NumberDRO trunkData = trunkNumberResponse.getData();
        log.info("[{}]，根据中继号码查询外呼号码返回response：{}",TAG,JSON.toJSONString(trunkData));

        return trunkData.getTelNumber();
    }


    /**
     * 获取外部店铺ID
     * @param orderId
     * @param workId
     * @return
     */
    private String getExternalShopId(Long orderId,Long workId){
        OrderExternalShop orderExternalShop = orderExternalShopService.findByOrderIdAndWorkId(orderId, workId);
        if(Objects.isNull(orderExternalShop) || StringUtil.isBlank(orderExternalShop.getExternalShopId())){
            return com.zmn.consts.GlobalConsts.SPLITER_EMPTY;
        }

        return orderExternalShop.getExternalShopId();
    }

    /**
     * 根据店铺ID查询2次
     * @param externalShopId
     * @param cityId
     * @return
     */
    private List<MarketingShopDRO> getMarketingShopListWithExternalShopId(String externalShopId,Integer cityId){
        // 查询店铺电话
        MarketingShopVerifyQuery marketingShopPhoneQuery = new MarketingShopVerifyQuery();
        if(StringUtil.isNotBlank(externalShopId)){
            marketingShopPhoneQuery.setThrShopId(externalShopId);
        }
        marketingShopPhoneQuery.setStatus(GlobalConsts.YES);

        log.info("[{}],根据三方店铺ID/电话、城市查询可核销的店铺电话入参：{}",TAG,JSON.toJSONString(marketingShopPhoneQuery));
        ResponseDTO<List<MarketingShopDRO>> shopPhoneResponse = marketingShopListRemoteService.listVerifyShopByQuery(marketingShopPhoneQuery);
        if(!shopPhoneResponse.isSuccess() || CollectionUtil.isNullOrEmpty(shopPhoneResponse.getData())){
            log.error("[{}],根据三方店铺ID/电话、城市查询可核销的店铺电话请求失败，失败原因：{}",TAG, shopPhoneResponse.getMessage());

            return Collections.emptyList();
        }

        List<MarketingShopDRO> shopPhoneList = shopPhoneResponse.getData();
        log.info("[{}]，根据三方店铺ID/电话、城市查询可核销的店铺电话返回response：{}",TAG,JSON.toJSONString(shopPhoneList));

        // 取出第一条有店铺电话的
        Optional<MarketingShopDRO> marketingShopPramsOptional = shopPhoneList.stream()
                .filter(shop -> StringUtil.isNotBlank(shop.getShopPhone()))
                .findFirst();
        String shopPhone = GlobalConsts.SPLITER_EMPTY;

        if(marketingShopPramsOptional.isPresent()){
            MarketingShopDRO marketingShopPrams = marketingShopPramsOptional.get();
            shopPhone = marketingShopPrams.getShopPhone();
        }

        if(StringUtil.isBlank(shopPhone)){
            log.error("[{}],根据三方店铺ID/电话、城市查询可核销的店铺电话返回店铺电话为空",TAG);

            return shopPhoneList;
        }

        log.error("[{}],根据三方店铺ID/电话、城市查询可核销的店铺电话response：{}",TAG,shopPhone);

        // 查询店铺列表
        MarketingShopVerifyQuery marketingShopVerifyQuery = new MarketingShopVerifyQuery();
        marketingShopVerifyQuery.setShopPhone(shopPhone);
        marketingShopVerifyQuery.setCityId(cityId);
        marketingShopVerifyQuery.setStatus(GlobalConsts.YES);

        log.info("[{}],根据三方店铺ID/电话、城市查询可核销的店铺信息入参：{}",TAG,JSON.toJSONString(marketingShopVerifyQuery));
        ResponseDTO<List<MarketingShopDRO>> listResponse = marketingShopListRemoteService.listVerifyShopByQuery(marketingShopVerifyQuery);
        if(!listResponse.isSuccess() || CollectionUtil.isNullOrEmpty(listResponse.getData())){
            log.error("[{}],根据三方店铺ID/电话、城市查询可核销的店铺信息请求失败，失败原因：{}",TAG, listResponse.getMessage());

            return Collections.emptyList();
        }

        List<MarketingShopDRO> marketList = listResponse.getData();
        log.info("[{}]，根据三方店铺ID/电话、城市查询可核销的店铺信息返回response：{}",TAG,JSON.toJSONString(shopPhoneList));

        return marketList;
    }


    /**
     * 店铺电话查询
     * @param calledNumber
     * @param cityId
     * @return
     */
    private List<MarketingShopDRO> getMarketingShopListWithCalledNumber(String calledNumber,Integer cityId){
        // 查询店铺列表
        MarketingShopVerifyQuery marketingShopPhoneQuery = new MarketingShopVerifyQuery();
        if(StringUtil.isNotBlank(calledNumber)){
            marketingShopPhoneQuery.setShopPhone(calledNumber);
        }
        marketingShopPhoneQuery.setCityId(cityId);
        marketingShopPhoneQuery.setStatus(GlobalConsts.YES);

        log.info("[{}],根据三方店铺ID/电话、城市查询可核销的店铺入参：{}",TAG,JSON.toJSONString(marketingShopPhoneQuery));
        ResponseDTO<List<MarketingShopDRO>> marketingShopListResponse = marketingShopListRemoteService.listVerifyShopByQuery(marketingShopPhoneQuery);
        if(!marketingShopListResponse.isSuccess() || CollectionUtil.isNullOrEmpty(marketingShopListResponse.getData())){
            log.error("[{}],根据三方店铺ID/电话、城市查询可核销的店铺请求失败，失败原因：{}",TAG, marketingShopListResponse.getMessage());

            return Collections.emptyList();
        }

        List<MarketingShopDRO> marketList = marketingShopListResponse.getData();
        log.info("[{}]，根据三方店铺ID/电话、城市查询可核销的店铺返回response：{}",TAG,JSON.toJSONString(marketList));

        return marketList;
    }
}
